package com.bjsdzk.collector.utils;

import com.bjsdzk.collector.one2one.CollectorServer;

import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.Arrays;

import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * Created by zealdin on 2017/6/21.
 */
public class Utils {

	private static Logger logger = LoggerFactory.getLogger(Utils.class);

    public static byte[] reversal(byte[] bytes) {
        if (bytes.length != 2) {
            return bytes;
        }
        return new byte[] { bytes[1] , bytes[0] };
    }

    public static int toInt(byte[] bytes, int offset) {
        int ret = 0;
        for (int i=0; i<4 && i+offset<bytes.length; i++) {
            ret <<= 8;
            ret |= (int)bytes[i] & 0xFF;
        }
        return ret;
    }

    public static int bytestoint(byte[] bytes, int i) {
        return bytestoint(bytes,i,1);
    }
    public static int bytestoint(byte[] bytes, int i,int j) {
        return toInt(getbytes(bytes,i,j),0);
    }
    public static Integer bytestointerger(byte[] bytes, int i,int j) {
        return bytes2Int(bytes,i,j);
    }

    public static int bytes2Int(byte[] b, int start,int len) {
        int sum = 0;
        int end = start + len;
        for (int i = start; i < end; i++) {
            int n = ((int)b[i]) & 0xff;
            n <<= (--len) * 8;
            sum += n;
        }
        return sum;
    }

    public static byte[] getbytes(byte[] bytes, int i) {
        return  getbytes(bytes,i,1);
    }

    public static byte[] getbytes(byte[] bytes, int i,int j) {
        return Arrays.copyOfRange(bytes, i , i + j);
    }

    public static Long toLong(byte[] bytes, int offset) {
        long result = 0;
        for (int i=0; i<8 && i+offset<bytes.length; i++) {
            result <<= 8;
            result |= (bytes[i] & 0xFF);
        }
        return result;
    }
    

public static String byteToHex(byte b){  
    String hex = Integer.toHexString(b & 0xFF);  
    if(hex.length() < 2){  
        hex = "0" + hex;  
    }  
    return hex;  
}

    public static String bytes2String(byte[] bytes, int i,int j) {
        return bytes2String(getbytes(bytes,i,j));
    }
    public static String bytes2String(byte[] bytes, int i) {
        return bytes2String(bytes,i,1);
    }

    public static String bytes2String(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X", b));
        }
        return sb.toString();
    }

    public static byte[] copyAndAddbyteArray(int startlength,byte[] innerBytes) {
		byte [] newArr = new byte[innerBytes.length+startlength];
		System.arraycopy(innerBytes, 0,newArr, startlength, innerBytes.length);
		return newArr;
    }

    public static byte convert(String a) {
        return (byte) (Integer.parseInt(a, 16) & 0xff);
    }

    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }

    public static byte[] backByte(byte[] buff){
        for (int i=0;i<buff.length;i++){
            int b=0;
            for (int j=0;j<8;j++){
                int bit = (buff[i]>>j&1)==0?1:0;
                b += (1<<j)*bit;
            }
            buff[i]=(byte)b;
        }
        return buff;
    }

    public static String toBinary( byte[] bytes )
    {
        StringBuilder sb = new StringBuilder(bytes.length * Byte.SIZE);
        for( int i = 0; i < Byte.SIZE * bytes.length; i++ ) {
            sb.append((bytes[i / Byte.SIZE] << i % Byte.SIZE & 0x80) == 0 ? '0' : '1');
        }
        return sb.toString();
    }

    public static String toBinary( byte[] bytes,int i ,int j ) {
        return toBinary(getbytes(bytes, i, j));
    }

    public static String toBinary( byte[] bytes,int i ) {
        return toBinary(getbytes(bytes, i, 1));
    }

    public static int toBinaryToint( byte[] bytes,int start,int end ) {
        int value = Integer.parseInt(toBinary(bytes).substring(start, end), 2);
        return value;
    }
    public static int toBinaryToint( byte[] bytes,int start) {
        int value = Integer.parseInt(toBinary(bytes).substring(start), 2);
        return value;
    }

    public static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1) {
            return null;
        }
            byte[] result = new byte[hexStr.length() / 2];
            for (int i = 0; i < hexStr.length() / 2; i++) {
                int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
                int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
                result[i] = (byte) (high * 16 + low);
            }
            return result;
        }

    public static String parseByte2HexStr(byte buf[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
                sb.append(hex.toUpperCase());
            }
            return sb.toString();
        }
    
    public static void printBytes(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X ", b));
        }
        logger.info("接收到回复消息: " + sb.toString());
    }
    
    public static String printBytes(byte[] bytes,int port,String name ) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X ", b));
        }
        logger.info(name+"==>port:" + port + "==>"+"接收到回复消息: " + sb);
        return  sb.toString();
    }

    public static String printBytes(byte[] bytes,int port ) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X ", b));
        }
        logger.info("parse after data==>port:" + port + "==>"+sb);
        return  sb.toString();
    }

    public static String bytesToHex(byte[] bytes) {
        StringBuilder buf = new StringBuilder(bytes.length * 2);
        for(byte b : bytes) { // 使用String的format方法进行转换
            buf.append(String.format("%02x", new Integer(b & 0xff)));
        }

        return buf.toString();
    }
    
    public static String binary(byte[] bytes, int radix){
        return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数
    }
    
	public static String checkNumFisrt(String cmd) {
		int sum = 0;
		if (cmd == null || cmd.trim().equals("")) {
			return "";
		}

		byte[] bytes = new byte[cmd.length() / 2];
		for (int i = 0; i < cmd.length() / 2; i++) {
			String subStr = cmd.substring(i * 2, i * 2 + 2);
			bytes[i] = (byte) Integer.parseInt(subStr, 16);

			sum += (0xff & bytes[i]);
		}
        String checkSumHex = Integer.toHexString(sum & 0xFF);
        if (checkSumHex.length() == 1) {
            checkSumHex = "0" + checkSumHex;
        }
		return checkSumHex.toUpperCase();
	}
	public static String checkNumFisrtAll(String cmd) {
		int sum = 0;
		if (cmd == null || cmd.trim().equals("")) {
			return "";
		}

		byte[] bytes = new byte[cmd.length() / 2];
		for (int i = 0; i < cmd.length() / 2; i++) {
			String subStr = cmd.substring(i * 2, i * 2 + 2);
			bytes[i] = (byte) Integer.parseInt(subStr, 16);

			sum += (0xff & bytes[i]);
		}
        String checkSumHex = Integer.toHexString(sum & 0xFF);
        if (checkSumHex.length() == 1) {
            checkSumHex = "0" + checkSumHex;
        }
		return (cmd+checkSumHex).toUpperCase();
	}
	
	  public static String calcSum( byte[] src) {
		  
	        int sum = 0;
	        for (byte b : src) {
	            sum += (0xff & b);
	        }
	        String checkSumHex = Integer.toHexString(sum & 0xFF);
	        if (checkSumHex.length() == 1) {
	            checkSumHex = "0" + checkSumHex;
	        }
	        return new String (src)+checkSumHex;
	    }
	
	public static String checkNumSecond(String cmd)  {
		if (cmd == null || cmd.trim().equals("")) {
			return "cmd不能为空";
		}
		byte[] bytes = new byte[cmd.length() / 2];
		for (int i = 0; i < cmd.length() / 2; i++) {
			String subStr = cmd.substring(i * 2, i * 2 + 2);
			bytes[i] = (byte) Integer.parseInt(subStr, 16);
		}
		int crc = CRC16.calcCrc16(bytes);
		String hex = String.format("%04x", ((crc & 0xFF) <<8) + ((crc & 0xff00) >>8));
		return hex.toUpperCase();
	}
	
	public static String checkNumSecondAll(String cmd)  {
		if (cmd == null || cmd.trim().equals("")) {
			return "cmd不能为空";
		}
		byte[] bytes = new byte[cmd.length() / 2];
		for (int i = 0; i < cmd.length() / 2; i++) {
			String subStr = cmd.substring(i * 2, i * 2 + 2);
			bytes[i] = (byte) Integer.parseInt(subStr, 16);
		}
		int crc = CRC16.calcCrc16(bytes);
		String hex = String.format("%04x", ((crc & 0xFF) <<8) + ((crc & 0xff00) >>8));
		return (cmd+hex).toUpperCase();
	}

    public static String add106cmd(String deviceHex,boolean readFlag,String address, int length,String data)  {
        if(readFlag){
            return  checkNumSecondAll(Utils.addStr(deviceHex, "03", address, String.format("%04x", length)));
        }else {
            return checkNumSecondAll(Utils.addStr(deviceHex, "10", address, String.format("%04x", length),String.format("%02x", length*2),data));
        }
    }

    public static String add117cmd(String deviceHex,boolean readFlag,String address, int length)  {
        if(readFlag){
            return  "68"+checkNumFisrtAll(Utils.addStr("F0",deviceHex, "03", address, String.format("%04x", length)));
        }else {
            return "";
        }
    }

    public static String[] gancmd(int partition){
        int[] start={0,512,1024,1536};
        String len = String.format("%04x", 20);
        String [] cmdAll=new String[partition];
        for (int i = 0; i <partition ; i++) {
            cmdAll[i]=Utils.checkNumSecondAll("0103"+String.format("%04x", start[i])+len);
        }
        return cmdAll;
    }

    public static String addStr(String ... args) {
        StringBuilder sb = new StringBuilder();
        for(String temp:args) {
            sb.append(temp);
        }
        return sb.toString();
    }
	
    

    public static void main(String[] args) {
    	String str="68F0011000040001020001";
    	String calcSum = calcSum(str.getBytes());
    	System.out.println(calcSum);
    }
}
